package net.hn.hnms.biz.support.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import net.hn.hnms.biz.support.company.domain.dto.ChartDto;
import net.hn.hnms.biz.support.company.domain.vo.ChartVo;
import net.hn.hnms.biz.support.domain.SupportHisPo;
import net.hn.hnms.biz.support.domain.SupportNowPo;
import net.hn.hnms.biz.support.domain.dto.BaseSensorCoordDto;
import net.hn.hnms.biz.support.domain.dto.ResistanceCurveDto;
import net.hn.hnms.biz.support.domain.dto.SupportCloudDto;
import net.hn.hnms.biz.support.domain.dto.SupportHisDto;
import net.hn.hnms.biz.support.domain.vo.*;
import net.hn.hnms.biz.support.group.domain.MineNowAlarmVo;
import net.hn.hnms.biz.support.mapper.CoalMineSysPointMapper;
import net.hn.hnms.biz.support.mapper.HolderHisMapper;
import net.hn.hnms.biz.support.mapper.HolderNowMapper;
import net.hn.hnms.biz.support.service.SupportService;
import net.hn.hnms.biz.support.utils.OweDateUtils;
import net.hn.hnms.sys.common.core.constant.Constants;
import net.hn.hnms.sys.common.core.exception.HuaNengException;
import net.hn.hnms.sys.common.core.utils.DateUtils;
import net.hn.hnms.sys.common.core.utils.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
public class SupportServiceImpl implements SupportService {

    @Resource
    private HolderNowMapper holderNowMapper;
    @Resource
    private HolderHisMapper holderHisMapper;

    @Resource
    private CoalMineSysPointMapper coalMineSysPointMapper;

    @Override
    public List<HolderResistanceMoveVo> selectNowList(String mineCode) {
        //查询支架实时表
        List<SupportNowPo> supportNowPos = holderNowMapper.selectList(new LambdaQueryWrapper<SupportNowPo>().eq(StringUtils.isNotBlank(mineCode), SupportNowPo::getMineCode, mineCode));
        //支架压力集合
        TreeMap<Integer, SupportNowPo> mapPressure = new TreeMap<>();
        //支架位移集合
        TreeMap<Integer, SupportNowPo> mapMove = new TreeMap<>();
        //获取配置文件中支架压力的动态文本值  立柱压力
        String supportStr = coalMineSysPointMapper.supportTypeName("1", mineCode);
        //获取配置文件中的动态支架位移文本值   位移行程
        String moveStr = coalMineSysPointMapper.supportTypeName("2", mineCode);
        //遍历集合
        for (SupportNowPo t : supportNowPos) {
            //获取测点编码测点编码
            String pointCode = t.getPointCode();

            if (pointCode.contains(supportStr)) {
                mapPressure.put(Integer.parseInt(lastNumber(pointCode)), t);

            } else if (pointCode.contains(moveStr)) {
                mapMove.put(Integer.parseInt(lastNumber(pointCode)), t);
            }
        }
        List<HolderResistanceMoveVo> list = new ArrayList<>();
        mapPressure.forEach((key, value) -> {
            SupportNowPo supportNowPo = mapMove.get(key);
            HolderResistanceMoveVo holderResistanceMoveVo = new HolderResistanceMoveVo();
            holderResistanceMoveVo.setIndex(key);
            holderResistanceMoveVo.setDetectionLocation(supportStr + key);
            holderResistanceMoveVo.setResistanceValue(value.getPointValue());
            if (supportNowPo != null) {
                holderResistanceMoveVo.setMoveValue(supportNowPo.getPointValue());
            }
            holderResistanceMoveVo.setDateTime(value.getDataTime());
            list.add(holderResistanceMoveVo);
        });

        return list;
    }

    /**
     * 最大工作阻力变化曲线
     *
     * @param resistanceCurveDto
     * @return
     */
    @Override
    public List<ResistanceCurveVo> holderResistanceCurve(ResistanceCurveDto resistanceCurveDto) {
        Integer dateIntger = resistanceCurveDto.getDateIntger();
        if (dateIntger == 1) {
            //周
            resistanceCurveDto.setDateIntger(6);
        } else if (dateIntger == 2) {
            //月
            resistanceCurveDto.setDateIntger(30);
        } else if (dateIntger == 3) {
            resistanceCurveDto.setDateIntger(365);
        } else {
            resistanceCurveDto.setDateIntger(6);
        }
        String lib = resistanceCurveDto.getLib();
        if (lib.contains("压力")) {
//            resistanceCurveDto.setLib("支架压力");
            String typeName = coalMineSysPointMapper.supportTypeName("1", resistanceCurveDto.getMineCode());
            resistanceCurveDto.setLib(typeName);
        } else {
//            resistanceCurveDto.setLib("位移行程");
            String typeName = coalMineSysPointMapper.supportTypeName("2", resistanceCurveDto.getMineCode());
            resistanceCurveDto.setLib(typeName);
        }
        List<SupportHisDto> list = holderHisMapper.holderResistanceCurve(resistanceCurveDto);
        List<ResistanceCurveVo> collect = list.stream().map(t -> {
            //最大工作阻力变化曲线
            ResistanceCurveVo resistanceCurveVo = new ResistanceCurveVo();
            //时间
            resistanceCurveVo.setDateTime(t.getDataTime());
            //值
            resistanceCurveVo.setValue(t.getPointValue());
            return resistanceCurveVo;
        }).collect(Collectors.toList());
        //排序
        List<ResistanceCurveVo> resistanceCurveVoList = collect.stream().sorted(Comparator.comparing(ResistanceCurveVo::getDateTime).reversed()).collect(Collectors.toList());
        return resistanceCurveVoList;
    }

    /**
     * 统计信息
     *
     * @return
     */
    @Override
    public StatisticalInformationVo statisticalInformation(String mineCode) {
        String typeName = coalMineSysPointMapper.supportTypeName("1", mineCode);
        SupportNowPo supportNowPo = holderNowMapper.selectSupportNowPoOne(typeName, mineCode);
        //值
        BigDecimal pointValue = supportNowPo.getPointValue();
        //位置
        String pointCode = supportNowPo.getPointCode();
        Integer digitalString = 0;
        if ("620824009734".equals(mineCode)) {
            //砚北
            digitalString = isDigitalString(pointCode);
        } else if ("150621011038".equals(mineCode)) {
            //高头窑
//            digitalString = isDigitalString(pointCode);
            digitalString = Integer.parseInt(middleNumber(pointCode));
        }

        if (supportNowPo == null) {
            throw new HuaNengException(Constants.FAIL, "未查询到数据");
        }
        //统计信息实体
        StatisticalInformationVo statisticalInformationVo = new StatisticalInformationVo();
        //最大支架阻力
        statisticalInformationVo.setMaxHolderResistance(pointValue);
        //最大阻力位置
        statisticalInformationVo.setMaxHolderLocation(digitalString);
        //在线测点

        Long aLong = holderNowMapper.selectCount(new LambdaQueryWrapper<SupportNowPo>().eq(StringUtils.isNotBlank(mineCode), SupportNowPo::getMineCode, mineCode));
        statisticalInformationVo.setOnLinePoint(aLong.intValue());

        //报警测点数
        // TODO 没有报警表
        statisticalInformationVo.setPolicePoint(0);
        return statisticalInformationVo;
    }

    /**
     * 支架检测/支架位移曲线*
     *
     * @param id
     * @return
     */
    @Override
    public EchartVo holderPressure(String id, String mineCode) {
        String str = "";
        if ("1".equals(id)) {
            //获取配置文件中支架压力的动态文本值  立柱压力
            String supportStr = coalMineSysPointMapper.supportTypeName("1", mineCode);
            if (StringUtils.isEmpty(supportStr)) {
                //获取不到压力文本
                str = "压力";
            } else {
                str = supportStr;
            }
        } else if ("2".equals(id)) {
            str = "行程";
        } else {
            str = "压力";
        }
//        LambdaQueryWrapper<SupportNowPo> wrapper = new LambdaQueryWrapper<>();
//        wrapper.like(SupportNowPo::getPointCode, str);
//        List<SupportNowPo> supportNowPos1 = holderNowMapper.selectList(wrapper);
        List<SupportNowPo> supportNowPos = holderNowMapper.selectNowList(str, mineCode);
        //排序
//        List<SupportNowPo> supportNowPos = supportNowPos1.stream().sorted(Comparator.comparing(SupportNowPo::getPointCode)).collect(Collectors.toList());
        EchartVo echartVo = new EchartVo();
        List<Date> dateList = new ArrayList<>();
        List<Integer> integerList = new ArrayList<>();
        List<BigDecimal> bigDecimalList = new ArrayList<>();
        for (SupportNowPo supportNowPo : supportNowPos) {
            dateList.add(supportNowPo.getDataTime());
            bigDecimalList.add(supportNowPo.getPointValue());
            integerList.add(Integer.parseInt(lastNumber(supportNowPo.getPointCode())));
        }
        echartVo.setDate(dateList);
        echartVo.setValue(bigDecimalList);
        echartVo.setNumber(integerList);

        return echartVo;
    }

    @Override
    public List<List<Object>> holdernNephogram(SupportCloudDto supportCloudDto) {
        Integer dateIntger = supportCloudDto.getDateIntger() != null ? supportCloudDto.getDateIntger() : 1;
        if (dateIntger == 1) {
            //周
            supportCloudDto.setDateIntger(6);
        } else if (dateIntger == 2) {
            //月
            supportCloudDto.setDateIntger(30);
        } else if (dateIntger == 3) {
            //年
            supportCloudDto.setDateIntger(365);
        } else {
            supportCloudDto.setDateIntger(6);
        }
        //获取支架编号
        String lib = supportCloudDto.getLib() != null ? supportCloudDto.getLib() : "1";
        //支架压力
        String pressure = "";
        if ("620824009734".equals(supportCloudDto.getMineCode())) {
            //砚北
            pressure = "NewSite_XTKC_168架_1支架压力" + lib;
        } else if ("150621011038".equals(supportCloudDto.getMineCode())) {
            //高头窑
            //将1变为001 规则
            lib = changeDigit(lib);
            pressure = "NewSite_Group2_OPC_电液控_支架集_" + lib + "_立柱压力";
        }
        supportCloudDto.setLib(pressure);
//        List<SupportHisDto> pressureList1 = holderHisMapper.holdernNephogram(supportCloudDto);
        List<SupportHisDto> pressureList1 = holderHisMapper.holdernNephogram1(supportCloudDto);
//        List<SupportHisDto> pressureList = pressureList1.stream().sorted(Comparator.comparing(SupportHisDto::getDataTime).reversed()).collect(Collectors.toList());
        //位移行程
        String move = "";
        if ("620824009734".equals(supportCloudDto.getMineCode())) {
            //砚北
            move = "NewSite_XTKC_168架_1位移行程" + lib;
        } else if ("150621011038".equals(supportCloudDto.getMineCode())) {
            //高头窑
            lib = changeDigit(lib);
            move = "NewSite_Group2_OPC_电液控_支架集_" + lib + "_前溜行程";
        }
        supportCloudDto.setLib(move);
//        List<SupportHisDto> moveList1 = holderHisMapper.holdernNephogram(supportCloudDto);
        List<SupportHisDto> moveList1 = holderHisMapper.holdernNephogram1(supportCloudDto);
//        List<SupportHisDto> moveList = moveList1.stream().sorted(Comparator.comparing(SupportHisDto::getDataTime).reversed()).collect(Collectors.toList());

        List<List<Object>> list = new ArrayList<>();
        int count = 0;
        for (SupportHisDto supportHisDto : pressureList1) {
            List<Object> san = new ArrayList<>();
            san.add(moveList1.get(count).getPointValue());
            san.add(supportHisDto.getDataTime());
            san.add(supportHisDto.getPointValue());
            count++;
            list.add(san);
        }

        return list;
    }

    /**
     * //将1变成001，如果想变成0001---“%04d”
     *
     * @param lib
     * @return
     */
    private String changeDigit(String lib) {
        return String.format("%03d", Integer.parseInt(lib));//将1变成001，如果想变成0001---“%04d”
    }

    /**
     * 获取支架压力最大值
     *
     * @return
     */
    @Override
    public SupportNowPo selectSupportNowPoOne(String mineCode) {
        //获取压力文本
        String typeName = coalMineSysPointMapper.supportTypeName("1", mineCode);
        SupportNowPo supportNowPo = holderNowMapper.selectSupportNowPoOne(typeName, mineCode);
        if (supportNowPo == null) {
            return new SupportNowPo();
        }
        return supportNowPo;
    }


    /**
     * 查询支架压力实时表所有煤矿的支架压力记录
     *
     * @return
     */
    @Override
    public Integer selectAllSupportPressurePoint() {
        //获取压力文本
        String typeName = coalMineSysPointMapper.supportTypeName("1", null);
        LambdaQueryWrapper<SupportNowPo> supportNowPoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        supportNowPoLambdaQueryWrapper.like(SupportNowPo::getPointCode, typeName);
        Long aLong = holderNowMapper.selectCount(supportNowPoLambdaQueryWrapper);
        return aLong.intValue();
    }

    /**
     * 支架报警曲线
     *
     * @param number
     * @return
     */
    @Override
    public ChartVo riskStatistics(String number) {
        ChartVo chartVo = new ChartVo();
        List<String> xlast = new ArrayList<>();
        List<BigDecimal> ylast = new ArrayList<>();
        List<ChartDto> list = null;
        //1-周，2-月
        if ("1".equals(number)) {
            //TODO 支架暂时没有报警表
//            list =abscissalarmAbnormalMapper.riskStatisticsWeek();
        }
        if ("2".equals(number)) {
//            list =abscissalarmAbnormalMapper.riskStatisticsMonth();
        }

//        for (ChartDto chartDto : list) {
//            xlast.add(new SimpleDateFormat("yyyy-MM-dd").format(chartDto.getTime()));
//            ylast.add(chartDto.getValue());
//        }
        chartVo.setXData(xlast);
        chartVo.setValeus(ylast);
        return chartVo;
    }

    /**
     * 查询支架报警,从支架历史表中查询今天的报警信息
     *
     * @return
     */
    @Override
    public List<SupportHisPo> todayAlar() {
        List<SupportHisPo> supportHisPoList = holderHisMapper.todayAlarm();
        if (supportHisPoList.isEmpty()) {
            return new ArrayList<SupportHisPo>();
        }
        return supportHisPoList;
    }

    /**
     * 配置表中根据index获取支架文本
     */
    @Override
    public String supportTypeName(String index, String mineCode) {
        return coalMineSysPointMapper.supportTypeName(index, mineCode);
    }

    /**
     * 配置表中 获取支架文本列表
     */
    @Override
    public List<String> supportTypeNameList(String mineCode) {
        return coalMineSysPointMapper.supportTypeNameList(mineCode);
    }

    /**
     * 获取公司端煤矿支架实时报警数
     *
     * @param companyCode
     * @return
     */
    @Override
    public List<MineNowAlarmVo> nowAlarm(String mineCode, String companyCode) {
        List<MineNowAlarmVo> list = holderNowMapper.selectNowNowAlarmCount(mineCode, companyCode);
        return list;
    }

    /**
     * 获取生产监控的支架数据BaseSensorTable表所有信息
     *
     * @return
     */
    @Override
    public List<BaseSensorCoordDto> getProductionZjjcBaseSensorTableAllList(String mineCode) {
        //获取压力文本
        //获取支架表中的所有数据
        String typeName = coalMineSysPointMapper.supportTypeName("1", mineCode);
        if (StringUtils.isEmpty(typeName)) {
            typeName = "压力";
        }
        List<SupportNowPo> supportNowPo = holderNowMapper.selectNowList(typeName, mineCode);
        if (supportNowPo.isEmpty()) {
            return new ArrayList<>();
        }
        Collections.sort(supportNowPo);
        return supportNowPo.stream().map(t -> {
            BaseSensorCoordDto baseSensorCoordDto = new BaseSensorCoordDto();
            //传感器编码
            baseSensorCoordDto.setPointCode(t.getPointCode());
            //传感器名称 生产数据没有传感器名称
            baseSensorCoordDto.setLocation(t.getPointCode());
            //传感器类型编码
            baseSensorCoordDto.setSensorTypeCode(t.getSensorType() == null ? "zjzl" : t.getSensorType());
            //传感器类型名称
            baseSensorCoordDto.setSensorTypeName("支架");
            //x
            baseSensorCoordDto.setXCoordinate(new BigDecimal(0));
            //y
            baseSensorCoordDto.setYCoordinate(new BigDecimal(0));
            //z
            baseSensorCoordDto.setZCoordinate(new BigDecimal(0));

            return baseSensorCoordDto;
        }).collect(Collectors.toList());

    }

    @Override
    public HolderAnalyseVo getHolderAnalysis(String mineCode) {
        HolderAnalyseVo holderAnalyseVo = new HolderAnalyseVo();
        String endTime = DateUtils.getTime();
        // TODO 数据量太大返回有问题
        String startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.addHours(DateUtils.getNowDate(), -1));
        List<String> xData = OweDateUtils.getXData(startTime, endTime, "minutes");
        List<ChartAnaliseVo> chartAnaliseVoList = holderHisMapper.getHolderAnalysis(mineCode, startTime, endTime);
        holderAnalyseVo.setXData(xData);
        List<List<Object>> chartList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(chartAnaliseVoList)) {
            List<String> ylist = chartAnaliseVoList.stream().map(ChartAnaliseVo::getY).distinct().collect(Collectors.toList());
            List<String> yData = ylist.stream().sorted(Comparator.comparingInt(Integer::parseInt)).collect(Collectors.toList());
            holderAnalyseVo.setYData(yData);
            for (int i = 0; i < xData.size(); i++) {
                String time = xData.get(i);
                for (int i1 = 0; i1 < yData.size(); i1++) {
                    String zj = yData.get(i1);
                    ChartAnaliseVo chartAnaliseVo = chartAnaliseVoList.stream().filter(t -> t.getX().equals(time) && t.getY().equals(zj)).findFirst().orElse(new ChartAnaliseVo(time, zj, "0.0"));
                    List<Object> list = new ArrayList<>();
                    list.add(i);
                    list.add(i1);
                    list.add(Double.parseDouble(chartAnaliseVo.getType()));
                    chartList.add(list);
                }
            }
        }
        holderAnalyseVo.setChartAnaliseVoList(chartList);
        return holderAnalyseVo;
    }

    // 输入字符串，返回判断最后几位是否为字符并返回
    public static Integer isDigitalString(String pointCode) {
        //获取倒数第三位位
        String substring3 = pointCode.substring(pointCode.length() - 3);
        String substring2 = pointCode.substring(pointCode.length() - 2);
        String substring1 = pointCode.substring(pointCode.length() - 1);
        //判断是否数字
        if (isNumeric4(substring3)) {
            return Integer.parseInt(substring3);
//            mapPressure.put(Integer.parseInt(substring3), t);
        } else if (isNumeric4(substring2)) {
            return Integer.parseInt(substring2);
//            mapPressure.put(Integer.parseInt(substring2), t);
        } else {
            return Integer.parseInt(substring1);
//            mapPressure.put(Integer.parseInt(substring1), t);
        }
    }

    public String lastNumber(String code) {

        Pattern p = Pattern.compile("[0-9]+(?=[^0-9]*$)");
        Matcher matcher = p.matcher(code);
        if (matcher.find()) {
            return matcher.group();
        }
        return "";
    }

    private String middleNumber(String code) {
        //仅适用于高头窑支架
        //举例：NewSite_Group2_OPC_电液控_支架集_002_前溜行程     输出：002
        String reg = "(?<=支架集_).*?(?=_)";
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(code);
        if (matcher.find()) {
            return matcher.group();
        }
        return "0";
    }


    // 判断字符串是否为数字
    public static boolean isNumeric4(String str) {
        return str != null && str.chars().allMatch(Character::isDigit);
    }

}
